package main

import (
	"fmt" // 添加 fmt 包导入
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
	
	_ "volux/routers"
	"volux/utils"
	"volux/services"
	"volux/middleware"  // 添加 middleware 包导入
	"github.com/beego/beego/v2/core/logs"
	"github.com/beego/beego/v2/server/web"
	_ "volux/swagger"
)

// 全局服务实例
var (
	monitorService   *services.MonitorService
	discoveryService *services.DiscoveryService
	errorHandler     *services.ErrorHandler
	heartbeatService *services.HeartbeatService
	storageService   *services.StorageService
	qosManager       *services.QoSManager
	metricsService   *services.MetricsService
	alertService     *services.AlertService
	perfStoreService *services.PerfStoreService
	healthService    *services.HealthService
)

func init() {
	// 配置日志格式
	logs.SetLogFuncCall(true)
	logs.SetLogFuncCallDepth(3)
	logs.SetLogger(logs.AdapterFile, `{
		"filename": "logs/volux.log",
		"level": 7,
		"maxlines": 0,
		"maxsize": 0,
		"daily": true,
		"maxdays": 10,
		"color": true,
		"separate": ["error", "warning", "info", "debug"],
		"prefix": "[VOLUX]",
		"flags": "date,time"  // 添加时间戳
	}`)
	
	// 配置控制台日志
	logs.SetLogger(logs.AdapterConsole, `{
		"level": 7,
		"color": true,
		"prefix": "[VOLUX]",
		"flags": "date,time"  // 添加时间戳
	}`)
	
	logs.Info("====================================")
	logs.Info("[VOLUX] Starting service initialization")
	logs.Info("====================================")
	
	logs.Info("Starting Volux initialization...")
	
	// 初始化配置
	if err := utils.InitConfig(); err != nil {
		logs.Critical("Failed to initialize config: %v", err)
		panic(err)
	}
	
	// 初始化客户端
	if err := utils.InitClients(); err != nil {
		logs.Critical("Failed to initialize clients: %v", err)
		panic(err)
	}
	
	// 初始化服务
	initServices()
	
	// 添加请求日志中间件
	reqLogger := &middleware.RequestLoggerMiddleware{}
	web.InsertFilter("/*", web.BeforeRouter, reqLogger.DumpRequest)
	web.InsertFilter("/*", web.FinishRouter, reqLogger.DumpResponse)
}

func initServices() {
	// 直接返回，不执行其余代码
	return

	// 初始化监控服务
	monitorService = services.NewMonitorService()
	
	// 初始化发现服务
	discoveryService = services.NewDiscoveryService()
	
	// 初始化错误处理服务
	errorHandler = services.NewErrorHandler()
	
	// 初始化心跳服务
	nodeID := web.AppConfig.DefaultString("gateway::node_id", "gateway-01")
	nodeName := web.AppConfig.DefaultString("gateway::node_name", "Gateway Node 1")
	heartbeatInterval := web.AppConfig.DefaultInt("gateway::heartbeat_interval", 5)
	
	var err error
	heartbeatService, err = services.NewHeartbeatService(nodeID, nodeName, heartbeatInterval)
	if err != nil {
		logs.Critical("Failed to initialize heartbeat service: %v", err)
		panic(err)
	}
	
	// 启动心跳服务
	heartbeatService.Start()
	
	// 等待etcd连接稳定
	maxRetries := web.AppConfig.DefaultInt("etcd::retry_times", 5)
	retryInterval := web.AppConfig.DefaultInt("etcd::retry_interval", 3)
	
	etcdClient, err := utils.WaitForEtcdConnection(maxRetries, retryInterval)
	if err != nil {
		logs.Critical("Failed to establish stable connection to etcd: %v", err)
		logs.Critical("Please check:")
		logs.Critical("1. Is etcd service running? (systemctl status etcd)")
		logs.Critical("2. Is etcd endpoint correct? (current: %s)", web.AppConfig.DefaultString("etcd::endpoints", ""))
		logs.Critical("3. Are etcd credentials correct?")
		logs.Critical("4. Is network accessible?")
		os.Exit(1)
	}
	
	logs.Info("Successfully connected to etcd")
	storageService = services.NewStorageService(etcdClient)
	
	// 初始化恢复服务
	recoveryService := services.NewRecoveryService(storageService, utils.GetSPDKClient())
	
	// 添加重试机制的资源恢复
	maxRecoveryRetries := web.AppConfig.DefaultInt("recovery::max_retries", 3)
	for i := 0; i < maxRecoveryRetries; i++ {
		err := recoveryService.RecoverResources()
		if err == nil {
			logs.Info("Successfully recovered resources")
			break
		}
		
		if i == maxRecoveryRetries-1 {
			logs.Critical("Failed to recover resources after %d attempts: %v", maxRecoveryRetries, err)
			logs.Critical("Cannot continue without resource recovery, stopping service...")
			os.Exit(1)
		}
		
		logs.Warning("Failed to recover resources, retry %d/%d: %v", i+1, maxRecoveryRetries, err)
		time.Sleep(time.Duration(retryInterval) * time.Second)
		
		// 重新检查etcd连接
		if !utils.CheckEtcdConnection(etcdClient) {
			etcdClient, err = utils.WaitForEtcdConnection(maxRetries, retryInterval)
			if err != nil {
				logs.Critical("Lost connection to etcd and failed to reconnect")
				os.Exit(1)
			}
			storageService = services.NewStorageService(etcdClient)
			recoveryService = services.NewRecoveryService(storageService, utils.GetSPDKClient())
		}
	}

	// 初始化QoS管理器
	qosManager = services.NewQoSManager(utils.GetSPDKClient())

	// 初始化指标监控服务
	metricsService = services.NewMetricsService(utils.GetSPDKClient())

	// 初始化告警服务
	alertService = services.NewAlertService()
	
	// 添加告警处理器
	emailHandler := &services.EmailAlertHandler{
		SMTPServer:  web.AppConfig.DefaultString("alert::smtp_server", "smtp.example.com"),
		SMTPPort:    web.AppConfig.DefaultInt("alert::smtp_port", 587),
		SMTPUser:    web.AppConfig.DefaultString("alert::smtp_username", ""),
		SMTPPass:    web.AppConfig.DefaultString("alert::smtp_password", ""),
		ToAddresses: strings.Split(web.AppConfig.DefaultString("alert::recipients", ""), ","),
	}
	alertService.AddHandler(emailHandler)
	
	// 初始化性能数据存储服务
	perfStoreService = services.NewPerfStoreService(utils.GetEtcdClient())
	
	// 初始化健康检查服务
	healthService = services.NewHealthService(alertService)
}

func main() {
	// 初始化日志
	utils.InitLog()

	// 在全局过滤器中注册请求体拷贝中间件，确保所有请求均可读取 body
	web.InsertFilter("*", web.BeforeRouter, middleware.BodyReaderMiddleware)

	// 启动定时任务获取子系统统计信息
	go func() {
		ticker := time.NewTicker(10 * time.Minute) // 调整为10分钟
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
				client := utils.GetSPDKClient()
				if client != nil {
					_, err := client.GetSubsystemStats()
					if err != nil {
						utils.LogError(fmt.Sprintf("Failed to get subsystem stats: %v", err))
					}
				}
			}
		}
	}()

	// 优雅关闭处理
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	
	go func() {
		<-c
		cleanup()
		os.Exit(0)
	}()
	
	// 启动 Beego 服务
	web.Run()
}

func cleanup() {
	if heartbeatService != nil {
		heartbeatService.Stop()
	}
	utils.CloseClients()
}